import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseListener;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.Point;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class DrwPlgn extends JPanel {

    final int INTERVAL = 3;
    final int MAXIMUM = 1000;

    private int width;
    private int height;
    private int delay;

    private int[] xCoords1 = new int[MAXIMUM];
    private int[] yCoords1 = new int[MAXIMUM];
    private int nmbrPnts1 = 0;

    private int[] xCoords2 = new int[MAXIMUM];
    private int[] yCoords2 = new int[MAXIMUM];
    private int nmbrPnts2 = 0;

    private int[] xCoords = new int[MAXIMUM];
    private int[] yCoords = new int[MAXIMUM];
    private int nmbrPnts = 0;

    private int[] xMoves = new int[MAXIMUM];
    private int[] yMoves = new int[MAXIMUM];

    private boolean afterFirst = false;
    private boolean building1 = true;
    private boolean building2 = false;

    private static boolean fromFile = false;
    private static boolean animate = false;
    private static double t = 0.0, dt = 0.03;
    private static String sfilename, tfilename;

    private Timer tmr;

    public DrwPlgn(int wdth, int hght, int dly) {
        width = wdth;
        height = hght;
        delay = dly;
        tmr = new Timer(delay, new TimerListener());
        addMouseListener(new msLstnr());
        setPreferredSize(new Dimension(width, height));
    }

    public void paintComponent(Graphics page) {
        page.setColor(Color.black);
        page.fillRect(0, 0, width, height);
        page.setColor(Color.green);
        page.drawPolyline(xCoords1, yCoords1, nmbrPnts1);
        page.drawPolyline(xCoords2, yCoords2, nmbrPnts2);
        if (animate) {
            page.setColor(Color.red);
            page.drawPolyline(xCoords, yCoords, nmbrPnts1);
        }
    }

    public static void main(String[] arguments) {
        JFrame plgnFrame;
        DrwPlgn plgnPanel;
        int wdth, hght, delay;

        if (arguments.length >= 3) {
            wdth = Integer.parseInt(arguments[0]);
            hght = Integer.parseInt(arguments[1]);
            delay = Integer.parseInt(arguments[2]);
            if (arguments.length == 5) {
                sfilename = arguments[3];
                tfilename = arguments[4];
                fromFile = true;
            }
            plgnFrame = new JFrame("Morph a Polygon");
            plgnPanel = new DrwPlgn(wdth, hght, delay);
            plgnFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            plgnFrame.getContentPane().add(plgnPanel);
            plgnFrame.pack();
            plgnFrame.setVisible(true);
        } else {
            System.out
                    .println("Usage is\n  java DrwPlgn <width> <height> <delay> [<source> <target>]");
        }
    }

    private void interpolate(double t) {
        for (int i = 0; i < nmbrPnts1; i++) {
            xCoords[i] = (int) ((double) xCoords1[i] + t
                    * (double) ((xCoords2[i] - xCoords1[i])));
            yCoords[i] = (int) ((double) yCoords1[i] + t
                    * (double) ((yCoords2[i] - yCoords1[i])));
        }
    }

    private void loadPoly(String filename, boolean sflag) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new FileReader(filename));
            String line;
            line = in.readLine();
            int numpts = Integer.parseInt(line);
            for (int i = 0; i < numpts; i++) {
                line = in.readLine();
                String nums[] = line.split(" ");
                if (sflag) {
                    xCoords1[i] = Integer.parseInt(nums[0]);
                    yCoords1[i] = Integer.parseInt(nums[1]);
                } else {
                    xCoords2[i] = Integer.parseInt(nums[0]);
                    yCoords2[i] = Integer.parseInt(nums[1]);
                }
            }
            if (sflag) {
                nmbrPnts1 = numpts;
                xCoords1[nmbrPnts1] = xCoords1[0];
                yCoords1[nmbrPnts1++] = yCoords1[0];
            } else {
                nmbrPnts2 = numpts;
                xCoords2[nmbrPnts2] = xCoords2[0];
                yCoords2[nmbrPnts2++] = yCoords2[0];
            }
            in.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    private class msLstnr implements MouseListener {
        public void mouseClicked(MouseEvent msEvnt) {
        }

        public void mouseEntered(MouseEvent msEvnt) {
            tmr.stop();
            t = 0.0;
            animate = false;
        }

        public void mouseExited(MouseEvent msEvnt) {
            animate = true;
            for (int i = 0; i < nmbrPnts1; i++) {
                xCoords[i] = xCoords1[i];
                yCoords[i] = yCoords1[i];
            }
            repaint();
            tmr.start();
        }

        public void mousePressed(MouseEvent msEvnt) {
            Point clicked = msEvnt.getPoint();
            int[] newXs, newYs;
            int coord;

            if (fromFile) {
                building1 = building2 = false;
                loadPoly(sfilename, true);
                loadPoly(tfilename, false);
                repaint();
            } else if (building1) {
                if (afterFirst && xCoords1[0] - INTERVAL < clicked.x
                        && clicked.x < xCoords1[0] + INTERVAL
                        && yCoords1[0] - INTERVAL < clicked.y
                        && clicked.y < yCoords1[0] + INTERVAL) {
                    building1 = false;
                    building2 = true;
                    xCoords1[nmbrPnts1] = clicked.x;
                    yCoords1[nmbrPnts1++] = clicked.y;
                    repaint();
                } else {
                    xCoords1[nmbrPnts1] = clicked.x;
                    yCoords1[nmbrPnts1++] = clicked.y;
                    if (afterFirst) {
                        repaint();
                    } else {
                        afterFirst = true;
                    }
                }
            } else if (building2) {
                if (afterFirst && xCoords2[0] - INTERVAL < clicked.x
                        && clicked.x < xCoords2[0] + INTERVAL
                        && yCoords2[0] - INTERVAL < clicked.y
                        && clicked.y < yCoords2[0] + INTERVAL) {
                    building2 = false;
                    xCoords2[nmbrPnts2] = clicked.x;
                    yCoords2[nmbrPnts2++] = clicked.y;
                    repaint();
                } else {
                    xCoords2[nmbrPnts2] = clicked.x;
                    yCoords2[nmbrPnts2++] = clicked.y;
                    if (afterFirst) {
                        repaint();
                    } else {
                        afterFirst = true;
                    }
                }
            } else {
            }
        }

        public void mouseReleased(MouseEvent msEvnt) {
        }
    }

    private class TimerListener implements ActionListener {
        public void actionPerformed(ActionEvent actnEvnt) {
            t += dt;
            if (t < 0.9999) {
                interpolate(t);
            }
            repaint();
        }
    }
}